package com.yulang.springbootnetty.webscoket;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.yulang.springbootnetty.enums.MsgActionEnum;
import com.yulang.springbootnetty.pojo.ChatMsg;
import com.yulang.springbootnetty.service.UsersService;
import com.yulang.springbootnetty.utils.ChatMsgs;
import com.yulang.springbootnetty.utils.JsonUtils;
import com.yulang.springbootnetty.utils.SpringUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

// 处理消息的handler
//TextWebSocketFrame 专门处理文本的对象
public class MyHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    //用于记录和管理所有的客户端
    public static ChannelGroup users = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {

        String text = textWebSocketFrame.text();
        Channel channel = channelHandlerContext.channel();
        DataContent content = JsonUtils.jsonToPojo(text,DataContent.class);
        if(content.getAction()== MsgActionEnum.CONNECT.type){
            String sendId = content.getChatMsg().getSenderId();
            UserChannelRel.put(sendId,channel);
        }else if(content.getAction()== MsgActionEnum.CHAT.type){
            ChatMsgs chatMsgs = content.getChatMsg();
            UsersService usersService = (UsersService) SpringUtil.getBean("usersServiceImpl");
            ChatMsg chatMsg = new ChatMsg();
            chatMsg.setAcceptUserId(chatMsgs.getReceiverId());
            chatMsg.setSendUserId(chatMsgs.getSenderId());
            chatMsg.setMsg(chatMsgs.getMsg());
            chatMsg.setSingFlag(0);
            usersService.saveMsg(chatMsg);
            chatMsgs.setMsgId(chatMsg.getId());
            DataContent dataContentMsg = new DataContent();
            dataContentMsg.setChatMsg(chatMsgs);

            // 发送消息
            // 从全局用户Channel关系中获取接受方的channel
            Channel receiverChannel = UserChannelRel.get(chatMsg.getAcceptUserId());
            if (receiverChannel == null) {
                // TODO channel为空代表用户离线，推送消息（JPush，个推，小米推送）
            } else {
                // 当receiverChannel不为空的时候，从ChannelGroup去查找对应的channel是否存在
                Channel findChannel = users.find(receiverChannel.id());
                if (findChannel != null) {
                    // 用户在线
                    receiverChannel.writeAndFlush(
                            new TextWebSocketFrame(
                                    JsonUtils.objectToJson(dataContentMsg)));
                } else {
                    // 用户离线 TODO 推送消息
            }
            }

        }else if(content.getAction()== MsgActionEnum.SIGNED.type){
            UsersService usersService = (UsersService) SpringUtil.getBean("usersServiceImpl");
            String msgIds = content.getExtand();
            String[] split = msgIds.split(",");
            List<String> list = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                if(StringUtils.isNotEmpty(split[i])){
                    list.add(split[i]);
                }
            }
            System.out.println(list);
            if(list!=null && list.size()>0){
                usersService.singed(list);
            }
        }else if(content.getAction()== MsgActionEnum.PULL_FRIEND.type){

        }else if (content.getAction() == MsgActionEnum.KEEPALIVE.type) {
            //  2.4  心跳类型的消息
            System.out.println("收到来自channel为[" + channel + "]的心跳包...");
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        users.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        users.remove(ctx.channel());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.channel().close();
        users.remove(ctx.channel());
    }
}
